#include<iostream>
#include<deque>
#include<cstring>
using namespace std;

int n, m;
const int N=1010;
int sign[4][N][N];
char arr[N][N];
int dx[]={0, 0, 1, -1};
int dy[]={1, -1, 0, 0};

void bfs(int num)
{
	memset(sign[num], -1, sizeof sign[num]);
	deque<pair<int, int>> q;
	for(int i=1; i<=n; i++)
	{
		for(int j=1; j<=m; j++)
		{
			if(arr[i][j]-'0' == num)
			{
				q.push_back({i, j});
				sign[num][i][j]=0;
			}
		}
	}
	
	while(q.size())
	{
		auto ch=q.front(); q.pop_front();
		int x=ch.first, y=ch.second;
		for(int k=0; k<4; k++)
		{
			int i=x+dx[k], j=y+dy[k];
			if(i<1 || j<1 || i>n || j>m) continue;
			if(arr[i][j] == '#') continue;
			int cnt=arr[i][j]=='.' ? 1:0;
			if(sign[num][i][j] == -1) 
			{
                if(cnt == 0)
                    q.push_front({i, j});
                else
                    q.push_back({i, j});
                sign[num][i][j] = sign[num][x][y] + cnt;
            }
			else if(sign[num][i][j]>sign[num][x][y]+cnt)
			{
				sign[num][i][j]=sign[num][x][y]+cnt;
			}
		}
		
		
		
	}
}

int main()
{
	cin>>n>>m;
	for(int i=1; i<=n; i++)
	{
		for(int j=1; j<=m; j++)
		{
			cin>>arr[i][j];
		}
	}
	
	
	bfs(1); bfs(2); bfs(3);
	int ret=0x3f3f3f3f;
	
	for(int i=1; i<=n; i++)
	{
		for(int j=1; j<=m; j++)
		{
			if(arr[i][j] == '#') continue;
			int x=sign[1][i][j], y=sign[2][i][j], z=sign[3][i][j];
			if(x==-1 || y==-1 || z==-1) continue;
			if(arr[i][j] == '.') ret=min(ret, x+y+z-2);
			else ret=min(ret, x+y+z);
		}
	}
	if(ret==0x3f3f3f3f) cout<<-1<<endl;
	else cout<<ret<<endl;
	return 0;
}
